﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesFile;
using System.IO;
using ESRI.ArcGIS.Geometry;
using System.Collections;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.DataSourcesGDB;
using System.Windows.Forms;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.ADF;
using ESRI.ArcGIS.Display;
using System.Text.RegularExpressions;
using ESRI.ArcGIS.Geoprocessor;
using ESRI.ArcGIS.Geoprocessing;

using PlanningGIS.Framework.Controls;
using System.Runtime.InteropServices;
using PlanningGIS.Win.Controls;
using PlanningGIS.ArcGIS.Custom;
using PlanningGIS.ArcGIS;

using PlanningGIS.Util.Log;
using PlanningGIS.MapSheet;

namespace PlanningGIS.DataConvert.model.DataTransformation
{
    /// <summary>
    /// 坐标转换类
    /// </summary>
    public static class DataTransformation
    {
        /// <summary>
        /// 坐标装换（根据源控制点集与目标控制点集使用二次多项式法AffineTransformation2D）
        /// </summary>
        /// <param name="FromPtColl">源控制点点集</param>
        /// <param name="ToPtColl">目标控制点点集</param>
        /// <param name="pGeo">待转换的图形</param>
        /// <returns>是否转换成功</returns>
        public static bool TransformGeo(IPointCollection FromPtColl, IPointCollection ToPtColl, IGeometry pGeo)
        {
            try
            {
                //判断给定的控制点是否合法
                if (FromPtColl.PointCount != ToPtColl.PointCount)
                {
                    //控制点不成对错误
                    return false;
                }
                if (FromPtColl.PointCount < 4)
                {
                    //控制点不能少于4个 
                    return false;
                }

                //定义控制点数组
                int ControlPtCnt = FromPtColl.PointCount;

                IPoint[] controlFromPoints = new IPoint[ControlPtCnt];
                IPoint[] controlToPoints = new IPoint[ControlPtCnt];

                for (int i = 0; i < ControlPtCnt; i++)
                {
                    controlFromPoints[i] = FromPtColl.get_Point(i);
                    controlToPoints[i] = ToPtColl.get_Point(i);
                }

                //创建AffineTransformation2D对象
                //必须使用IAffineTransformation2D3GEN
                //因为DefineFromControlPoints在IAffineTransformation2D中使用C-Style Arrays, 该对象在.NET中不可用.
                IAffineTransformation2D3GEN affineTransformation2D = new AffineTransformation2DClass();
                affineTransformation2D.DefineFromControlPoints(ref controlFromPoints, ref controlToPoints);

                ITransform2D pTransform2D = pGeo as ITransform2D;
                pTransform2D.Transform(esriTransformDirection.esriTransformForward, affineTransformation2D as ITransformation);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 坐标装换（根据转换关系）
        /// </summary>
        /// <param name="pTransformation">转换关系</param>
        /// <param name="pGeo">待转换的图形</param>
        /// <returns>是否转换成功</returns>
        public static bool TransformGeo(ITransformation pTransformation, IGeometry pGeo)
        {
            try
            {
                ITransform2D pTransform2D = pGeo as ITransform2D;
                pTransform2D.Transform(esriTransformDirection.esriTransformForward, pTransformation);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 从shape文件路径与文件名获取要素类
        /// </summary>
        /// <param name="sPath">路径</param>
        /// <param name="sFileName">文件名</param>
        /// <returns>要素类</returns>
        public static IFeatureClass GetFeatClsFromFile(string sPath, string sFileName)
        {
            IWorkspaceFactory pFactory = new ShapefileWorkspaceFactoryClass();
            DirectoryInfo dir = new DirectoryInfo(sPath);
            if (!dir.Exists)
            {
                dir.Create();
            }
            IFeatureWorkspace pWS = pFactory.OpenFromFile(sPath, 0) as IFeatureWorkspace;
            IFeatureClass pFeatCls = null;
            try
            {
                pFeatCls = pWS.OpenFeatureClass(sFileName);
            }
            catch (Exception ex)
            {
                LogHelper.WriteLog(ex);
                return null;
            }
            return pFeatCls;
        }

        /// <summary>
        /// 根据图形获取图幅列表
        /// </summary>
        /// <param name="pGeo">图形</param>
        /// <param name="pFeatCls">图幅结合表要素类</param>
        /// <param name="strTufuNumField">图号字段名称</param>
        /// <returns>图幅列表</returns>
        public static List<Mapsheet> GetTufusByGeom(IGeometry pGeo, IFeatureClass pFeatCls, string strTufuNumField)
        {
            if (pGeo is IEnvelope)
            {
                IPolygon polygon = ((IEnvelope)pGeo).ToPolygon();
                pGeo = polygon as IGeometry;
            }
            List<Mapsheet> pSheetNums = new List<Mapsheet>();
            if (pGeo == null || pGeo.IsEmpty)
                return pSheetNums;

            if (pFeatCls == null || pFeatCls.Fields.FindField(strTufuNumField) < 0) return null;

            int iTFIdx = pFeatCls.Fields.FindField(strTufuNumField);

            ISpatialFilter pSpatialFilter = new SpatialFilterClass();
            pSpatialFilter.Geometry = pGeo;
            pSpatialFilter.GeometryField = "SHAPE";
            pSpatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
            IFeatureCursor pFeatCur = pFeatCls.Search(pSpatialFilter, false);
            IFeature pFeat = pFeatCur.NextFeature();
            while (pFeat != null)
            {
                Mapsheet tufu1 = new Mapsheet();
                tufu1.Code = pFeat.get_Value(iTFIdx).ToString();
                tufu1.Geometry = pFeat.ShapeCopy as IPolygon;
                pSheetNums.Add(tufu1);
                pFeat = pFeatCur.NextFeature();
            }
            return pSheetNums;
        }

        /// <summary>
        /// 获取结合图要素类的全图幅列表
        /// </summary>
        /// <param name="pFeatCls">结合图要素类</param>
        /// <param name="strTufuNumField">图号字段名称</param>
        /// <returns>图幅列表</returns>
        public static List<Mapsheet> GetTufusAll(IFeatureClass pFeatCls, string strTufuNumField)
        {
            if (pFeatCls == null || pFeatCls.Fields.FindField(strTufuNumField) < 0) return null;

            int iTFIdx = pFeatCls.Fields.FindField(strTufuNumField);

            List<Mapsheet> pSheetNums = new List<Mapsheet>();
            IFeatureCursor pFeatCur = pFeatCls.Search(null, false);
            IFeature pFeat = pFeatCur.NextFeature();
            while (pFeat != null)
            {
                Mapsheet tufu1 = new Mapsheet();
                tufu1.Code = pFeat.get_Value(iTFIdx).ToString();
                tufu1.Geometry = pFeat.ShapeCopy as IPolygon;
                pSheetNums.Add(tufu1);
                pFeat = pFeatCur.NextFeature();
            }
            return pSheetNums;
        }

        /// <summary>
        /// 根据图幅列表获取控制点集
        /// 使用图幅角点作为控制点
        /// 不考虑图幅的点序问题，因此要求所有图幅结合表要素类都是使用相同的工具生成
        /// 如考虑点序问题，需要再对点的坐标位置进行比较判断，效率会较低
        /// 不考虑不同图幅的重复点问题
        /// </summary>
        /// <param name="lstTF">图幅列表</param>
        /// <param name="pFeatureClass">图幅结合表要素类</param>
        /// <param name="strTufuNumField">图号字段名称</param>
        /// <returns>控制点列表</returns>
        public static IPointCollection getControlPoints(List<Mapsheet> lstTF, IFeatureClass pFeatureClass, string strTufuNumField)
        {
            IPointCollection pPCAll = new MultipointClass();
            object Missing = Type.Missing;
            foreach (Mapsheet tf in lstTF)
            {
                IQueryFilter queryFilter = new QueryFilterClass();
                queryFilter.WhereClause = strTufuNumField + "= '" + tf.Code + "'";
                IFeatureCursor pFeatureCursor = pFeatureClass.Search(queryFilter, false);
                IFeature pFeature = pFeatureCursor.NextFeature();
                if (pFeature != null)
                {
                    IPolygon pPolygon = pFeature.Shape as IPolygon;
                    IPointCollection pPCSub = pPolygon as IPointCollection;

                    for (int i = 0; i < pPCSub.PointCount - 1; i++)
                    {
                        IPoint pPoint = pPCSub.get_Point(i);
                        pPCAll.AddPoint(pPoint, ref Missing, ref Missing);
                    }
                }
            }
            return pPCAll;
        }

        /// <summary>
        /// 获取空间参考
        /// </summary>
        /// <param name="pFeatureClass">要素类</param>
        /// <returns>空间参考</returns>
        public static ISpatialReference getSpatialReference(IFeatureClass pFeatureClass)
        {
            IGeoDataset pGeoDataset = (IGeoDataset)pFeatureClass;
            ISpatialReference pSpatialReference = pGeoDataset.SpatialReference;
            return pSpatialReference;
        }

        /// <summary>
        /// 创建目标库体
        /// </summary>
        /// <param name="path">目标工作空间的路径</param>
        /// <param name="workspaceType">工作空间类型</param>
        /// <returns></returns>
        public static IWorkspace GetTargetWorkspace(string path, zjgisWorkspaceType workspaceType)
        {
            try
            {
                IWorkspaceFactory pWorkspaceFactory;

                //获得路径和文件名（测试以下，仅选择驱动器看会有什么样的异常）
                int pos = path.LastIndexOf('\\');
                string strPath = path.Substring(0, pos + 1);
                string strName = path.Substring(pos + 1);

                //对于大比例尺的图幅，图号中有'.'，需要去掉，不然创建不了库体
                strName = strName.Replace(".", "");

                string fullPath;

                switch (workspaceType)
                {
                    case zjgisWorkspaceType.shp:
                        pWorkspaceFactory = new ShapefileWorkspaceFactoryClass();

                        //如果文件夹不存在，需要先创建
                        if (!Directory.Exists(path))
                            Directory.CreateDirectory(path);

                        return pWorkspaceFactory.OpenFromFile(path, 0);

                    case zjgisWorkspaceType.mdb:
                    case zjgisWorkspaceType.gdb:
                        //如果文件夹不存在，需要先创建（与Shape不一样，这里创建到上一级）
                        if (!Directory.Exists(strPath))
                            Directory.CreateDirectory(strPath);

                        if (workspaceType == zjgisWorkspaceType.mdb)
                        {
                            pWorkspaceFactory = new AccessWorkspaceFactoryClass();
                            fullPath = path + ".mdb";
                        }
                        else
                        {
                            pWorkspaceFactory = new FileGDBWorkspaceFactoryClass();
                            fullPath = path + ".gdb";
                        }

                        if ((workspaceType == zjgisWorkspaceType.mdb && File.Exists(fullPath)) ||
                            (workspaceType == zjgisWorkspaceType.gdb && Directory.Exists(fullPath)))
                        {
                            DialogResult dialogresult = MsgHelper.ShowYesNoCancelQueryMsgbox("目标工作空间已经存在，追加请点击“是”，删除原有数据并创建新工作空间请点击“否”，终止本次导出请点击“取消”。");
                            switch (dialogresult)
                            {
                                case DialogResult.Yes:
                                    return pWorkspaceFactory.OpenFromFile(fullPath, 0);

                                case DialogResult.No:
                                    try
                                    {
                                        if (workspaceType == zjgisWorkspaceType.mdb)
                                            File.Delete(fullPath);
                                        else
                                        {
                                            foreach (string filename in Directory.GetFiles(fullPath))
                                                File.Delete(filename);

                                            Directory.Delete(fullPath);
                                        }
                                    }
                                    catch (Exception e)
                                    {
                                        LogHelper.WriteLog("删除已有目标数据工作空间失败！" + e.Message, zjgisLogType.zjgisLogError);
                                        return null;
                                    }

                                    break;

                                case DialogResult.Cancel:
                                    return null;
                            }
                        }
                        break;

                    case zjgisWorkspaceType.sde:
                        LogHelper.WriteLog("坐标转换暂时不支持导出到SDE！", zjgisLogType.zjgisLogError);
                        return null;

                    default:
                        LogHelper.WriteLog("坐标转换工作空间类型异常，系统目前仅支持导出shp、mdb和gdb格式！", zjgisLogType.zjgisLogError);
                        return null;
                }

                IWorkspaceName pWorkspaceName = pWorkspaceFactory.Create(strPath, strName, null, 0);

                IName pName = (IName)pWorkspaceName;
                return (IWorkspace)pName.Open();

            }
            catch (Exception e)
            {
                LogHelper.WriteLog("创建目标库体失败！" + e.Message, zjgisLogType.zjgisLogError);
                return null;
            }
        }

        public static bool CreateFeatCls(IFeatureClass pFeatClsSource, string targetFeatClsName, ref IFeatureClass pFeatClsTarget, ref Hashtable fieldRelation, IWorkspace pTargetWs, ISpatialReference pSrTarget)
        {
            try
            {
                IFieldChecker pFieldChecker;
                pFieldChecker = new FieldCheckerClass();
                pFieldChecker.ValidateWorkspace = pTargetWs;

                IFeatureDataset pFeatDStarget = null;

                #region 验证要素类名称是否符合规范
                string fixedName = "";
                pFieldChecker.ValidateTableName(targetFeatClsName, out fixedName);
                if (targetFeatClsName != fixedName)
                {
                    LogHelper.WriteLog("目标要素类[" + targetFeatClsName + "]的名称不符合规范，系统自动将其改为[" + fixedName + "]");
                }
                #endregion

                #region 验证要各字段是否符合规范
                IFields pFields = pFeatClsSource.Fields;
                IClone pClone = pFields as IClone;
                IFields xFields = pClone.Clone() as IFields;

            

                //IClone pC = validatedFields as IClone;
                //IFields pFldsTarget = pC.Clone() as IFields;
                ////修改目标要素类的空间参考
                //for (int j = 0; j < pFldsTarget.FieldCount; j++)
                //{
                //    if (pFldsTarget.get_Field(j).Type == esriFieldType.esriFieldTypeGeometry)
                //    {
                //        IGeometryDefEdit pGeometryDefEdit = (IGeometryDefEdit)pFldsTarget.get_Field(j).GeometryDef;
                //        pGeometryDefEdit.SpatialReference_2 = pSrTarget;
                //    }
                //}

                //pFieldChecker.Validate(pFldsTarget, out enumFieldError, out validatedFields);

                //IVerticalCoordinateSystem pVerticalCoordinateSystem = new VerticalCoordinateSystemClass();
                int iShpIdxSource = pFeatClsSource.FindField(pFeatClsSource.ShapeFieldName);
                IGeometryDef pGeometryDef = pFeatClsSource.Fields.get_Field(iShpIdxSource).GeometryDef;
                //bool bHasZ = pFeatClsSource.Fields.get_Field(iShpIdxSource).GeometryDef.HasZ;


                //修改目标要素类的空间参考
                for (int j = 0; j < xFields.FieldCount; j++)
                {
                    if (xFields.get_Field(j).Type == esriFieldType.esriFieldTypeGeometry)
                    {
                        IGeometryDefEdit pGeometryDefEdit = (IGeometryDefEdit)xFields.get_Field(j).GeometryDef;
                        //pSrTarget.ZCoordinateUnit = null;
                        pGeometryDefEdit.SpatialReference_2 = pSrTarget;
                        //pGeometryDefEdit.HasM_2 = pGeometryDef.HasM;
                        //pGeometryDefEdit.HasZ_2 = pGeometryDef.HasZ;
                        //pGeometryDefEdit.GridCount_2 = pGeometryDef.GridCount;
                        //pGeometryDefEdit.AvgNumPoints_2 = pGeometryDef.AvgNumPoints;
                        //pGeometryDefEdit.GeometryType_2 = pGeometryDef.GeometryType;
                        pGeometryDefEdit.HasM_2 = pGeometryDef.HasM;
                        pGeometryDefEdit.HasZ_2 = pGeometryDef.HasZ;
                    }
                }

                //if (bHasZ)
                //{
                //    //ISpatialReference3 pSr3S = (ISpatialReference3)pFeatClsSource.Fields.get_Field(iShpIdxSource).GeometryDef.SpatialReference;
                //    //IVerticalCoordinateSystem pVerticalCoordinateSystem = pSr3S.VerticalCoordinateSystem;
                //    //if (pVerticalCoordinateSystem == null)
                //    //{
                //    //    ISpatialReference3 pSr3T = (ISpatialReference3)pSrTarget;
                //    //    pSr3T.VerticalCoordinateSystem = null;
                //    //}
                //    //else
                //    //{
                //    //    ISpatialReference3 pSr3T = (ISpatialReference3)pSrTarget;
                //    //    pSr3T.VerticalCoordinateSystem = pVerticalCoordinateSystem;
                //    //}
                //    //ISpatialReference3 pSr3T = (ISpatialReference3)pSrTarget;

                //    //pSr3T.VerticalCoordinateSystem = new UnknownCoordinateSystemClass() as IVerticalCoordinateSystem;
                //    //ISpatialReferenceFactory3 spatialReferenceFactory = new SpatialReferenceEnvironmentClass();
                //    //pSr3T.ZCoordinateUnit = spatialReferenceFactory.CreateUnit((int)esriSRUnitType.esriSRUnit_Meter) as ILinearUnit;

                //}
                IFields validatedFields = null;
                IEnumFieldError enumFieldError = null;
                pFieldChecker.Validate(xFields, out enumFieldError, out validatedFields);
                fieldRelation = new Hashtable();

                //测试一下，字段是不是一一对应的
                for (int j = 0; j < pFields.FieldCount; j++)
                {
                    fieldRelation.Add(validatedFields.get_Field(j).Name, pFields.get_Field(j).Name);
                }

                #endregion


                //对于shape，判断要素类是否存在，对于mdb和gdb还要判断相应的数据集是否存在，另外shape不支持注记
                switch (pTargetWs.Type)
                {
                    case esriWorkspaceType.esriFileSystemWorkspace:
                        #region Shape不支持注记
                        if (pFeatClsSource.FeatureType != esriFeatureType.esriFTSimple)
                        {
                            LogHelper.WriteLog("目标注记类[" + fixedName + "]创建失败！导出Shape格式只支持点、线、面类型数据，不支持注记等其它类型。", zjgisLogType.zjgisLogError);
                            return false;
                        }
                        #endregion

                        #region 判断要素类是否已经存在
                        if (File.Exists(pTargetWs.PathName + "\\" + fixedName + ".shp"))
                        {
                            pFeatClsTarget = (pTargetWs as IFeatureWorkspace).OpenFeatureClass(fixedName);
                            return true;
                        }
                        #endregion

                        break;

                    case esriWorkspaceType.esriLocalDatabaseWorkspace:
                        IWorkspace2 pWorkspace2 = pTargetWs as IWorkspace2;

                        #region 判断数据集是否存在与目标工作空间中
                        if (pFeatClsSource.FeatureDataset != null)
                        {
                            IFeatureDataset pFeatDSsource = pFeatClsSource.FeatureDataset;

                            if (pWorkspace2 != null)
                            {
                                if (pWorkspace2.get_NameExists(esriDatasetType.esriDTFeatureDataset, pFeatDSsource.Name))
                                //如果存在数据集,修改数据集空间参考
                                {
                                    IGeoDatasetSchemaEdit pGeoDatasetEdit = (IGeoDatasetSchemaEdit)pFeatDSsource;
                                    pGeoDatasetEdit.AlterSpatialReference(pSrTarget);
                                    pFeatDStarget = (pTargetWs as IFeatureWorkspace).OpenFeatureDataset(pFeatDSsource.Name);
                                }
                                else
                                //如果不存在数据集，需要先创建数据集
                                {
                                    pFeatDStarget = (pTargetWs as IFeatureWorkspace).CreateFeatureDataset(pFeatDSsource.Name,
                                        pSrTarget);
                                }
                            }
                        }
                        #endregion

                        #region 判断要素类是否已经存在
                        if (pWorkspace2.get_NameExists(esriDatasetType.esriDTFeatureClass, fixedName))
                        {
                            pFeatClsTarget = (pTargetWs as IFeatureWorkspace).OpenFeatureClass(fixedName);
                            return true;
                        }
                        #endregion

                        break;

                    case esriWorkspaceType.esriRemoteDatabaseWorkspace:

                        return false;
                }

                switch (pFeatClsSource.FeatureType)
                {
                    #region 创建要素类
                    case esriFeatureType.esriFTSimple:
                        if (pFeatDStarget != null)
                        {
                            pFeatClsTarget = pFeatDStarget.CreateFeatureClass(fixedName, validatedFields, null, null,
                                esriFeatureType.esriFTSimple, "Shape", "");
                        }
                        else
                        {
                            //ESRI.ArcGIS.DataManagementTools.CreateFeatureclass pCreateFeatureclass = new ESRI.ArcGIS.DataManagementTools.CreateFeatureclass();
                            //pCreateFeatureclass.geometry_type = pGeometryDef.GeometryType;
                            //pCreateFeatureclass.has_m = pGeometryDef.HasM;
                            //pCreateFeatureclass.has_z = pGeometryDef.HasZ;
                            //pCreateFeatureclass.out_feature_class = pTargetWs.PathName + "\\" + fixedName;
                            //pCreateFeatureclass.out_name = fixedName;
                            //pCreateFeatureclass.out_path = pTargetWs.PathName;
                            //pCreateFeatureclass.spatial_reference = pSrTarget;
                            //ExecuteGPProcess(pCreateFeatureclass);
                            //pFeatClsTarget = (pTargetWs as IFeatureWorkspace).OpenFeatureClass(fixedName);

                            pFeatClsTarget = (pTargetWs as IFeatureWorkspace).CreateFeatureClass(fixedName, ((ESRI.ArcGIS.esriSystem.IClone)validatedFields).Clone() as IFields,
                                null, null, pFeatClsSource.FeatureType, pFeatClsSource.ShapeFieldName, "");

                            ////修改要素类空间参考
                            //int iShpIdxTarget = pFeatClsTarget.FindField(pFeatClsTarget.ShapeFieldName);
                            //IGeometryDefEdit pGeometryDefEdit = (IGeometryDefEdit)pFeatClsTarget.Fields.get_Field(iShpIdxTarget).GeometryDef;
                            //pGeometryDefEdit.SpatialReference_2 = pSrTarget;
                        }
                        LogHelper.WriteLog("目标要素类[" + fixedName + "]创建成功。");
                        break;
                    #endregion

                    #region 创建注记类
                    case esriFeatureType.esriFTAnnotation:
                        pFeatClsTarget = GeodatabaseHelper.CreateAnnotationFeatureClass((IWorkspace)pTargetWs, fixedName, validatedFields, pFeatClsSource, pFeatDStarget);
                        LogHelper.WriteLog("目标注记类[" + fixedName + "]创建成功。");
                        break;
                    #endregion

                    #region 暂不支持的类型
                    default:
                        LogHelper.WriteLog("系统暂不支持[" + pFeatClsSource.AliasName + "]数据（类型为[" + pFeatClsSource.FeatureType.ToString() + "]）的导出！", zjgisLogType.zjgisLogError);
                        return false;
                    #endregion
                }

                #region 给要素类赋别名

                if (pFeatClsTarget == null) return false;

                try
                {

                    IClassSchemaEdit pClassSchemaEdit = pFeatClsTarget as IClassSchemaEdit;
                    //shape没有别名
                    if (pClassSchemaEdit != null) pClassSchemaEdit.AlterAliasName(pFeatClsSource.AliasName);
                }
                catch (Exception ex)
                {
                    LogHelper.WriteLog("给目标要素类[" + fixedName + "]赋别名时出错：" + ex.Message, zjgisLogType.zjgisLogError);
                }
                #endregion

                return true;
            }
            catch (Exception e)
            {
                LogHelper.WriteLog("创建要素类[" + targetFeatClsName + "]失败！" + e.Message, zjgisLogType.zjgisLogError);
                return false;
            }
        }
        private static void ExecuteGPProcess(IGPProcess pGPProcess)
        {
            ESRI.ArcGIS.Geoprocessor.Geoprocessor gp = new ESRI.ArcGIS.Geoprocessor.Geoprocessor();
            IGeoProcessorResult results = (IGeoProcessorResult)gp.Execute(pGPProcess, null);
            string strMessage = "";
            if (results != null && results.Status != esriJobStatus.esriJobSucceeded)
            {
                strMessage += " 请检查数据!" + "\r\n";
            }
            strMessage += ReturnMessages(gp);
            MsgHelper.ShowInfomationMsgbox(strMessage);
        }

        private static string ReturnMessages(Geoprocessor gp)
        {
            StringBuilder sb = new StringBuilder();
            if (gp.MessageCount > 0)
            {
                for (int Count = 0; Count <= gp.MessageCount - 1; Count++)
                {
                    System.Diagnostics.Trace.WriteLine(gp.GetMessage(Count));
                    sb.AppendFormat("{0}\n", gp.GetMessage(Count));
                }
            }
            return sb.ToString();
        }
        public static ITransformation getTransformation(IPointCollection FromPtColl, IPointCollection ToPtColl)
        {
            try
            {
                //判断给定的控制点是否合法
                if (FromPtColl.PointCount != ToPtColl.PointCount)
                {
                    //控制点不成对错误
                    return null;
                }
                if (FromPtColl.PointCount < 4)
                {
                    //控制点不能少于4个 
                    return null;
                }

                //定义控制点数组
                int ControlPtCnt = FromPtColl.PointCount;

                IPoint[] controlFromPoints = new IPoint[ControlPtCnt];
                IPoint[] controlToPoints = new IPoint[ControlPtCnt];

                for (int i = 0; i < ControlPtCnt; i++)
                {
                    controlFromPoints[i] = FromPtColl.get_Point(i);
                    controlToPoints[i] = ToPtColl.get_Point(i);
                }

                //创建AffineTransformation2D对象
                //必须使用IAffineTransformation2D3GEN
                //因为DefineFromControlPoints在IAffineTransformation2D中使用C-Style Arrays, 该对象在.NET中不可用.
                IAffineTransformation2D3GEN affineTransformation2D = new AffineTransformation2DClass();
                affineTransformation2D.DefineFromControlPoints(ref controlFromPoints, ref controlToPoints);

                return affineTransformation2D as ITransformation;
            }
            catch
            {
                return null;
            }
        }

        public static bool TransformFeatureClass(IFeatureClass sourceFeatCls, IFeatureClass targetFeatCls, 
            ITransformation pTransformation, Hashtable fieldRelation, System.Windows.Forms.ProgressBar progressBar)
        {
            int count = 0;
            int errorCount = 0;
            int rightCount = 0;
            int totalCount = 0; 

            //没有源或没有目标要素类都不符合要求
            //if (sourceFeatCls == null || targetFeatCls == null)
            //{
            //   LogHelper.WriteErrLog("请设置数据源。");
            //    return false;
            //}
            //if (targetFeatCls == null)
            //{
            //   LogHelper.WriteErrLog("请设置目标数据。");
            //    return false;
            //}

            //if (fieldRelation == null || fieldRelation.Count == 0)
            //{
            //   LogHelper.WriteErrLog("请设置字段对应关系。");
            //}

            try
            {
                bool needInEditSeesionTarget;//创建目标要素时，是否需要打开编辑
                needInEditSeesionTarget = NeedInEditSession(targetFeatCls);

                if (needInEditSeesionTarget) StartEdit(targetFeatCls);

                IFeatureCursor pFeatCurSource;

                totalCount = sourceFeatCls.FeatureCount(null);
                progressBar.Maximum = totalCount;

                if (totalCount == 0) return true;

                pFeatCurSource = sourceFeatCls.Search(null, false);

                IFeature pSourceFeature;

                //bool deleteErr = false;

                ArrayList errFieldindexs = new ArrayList();

                #region 用IFeatureBuffer的方式创建要素
                IFeatureCursor pTargetFeatCursor;
                IFeatureBuffer pTargetFeatBuffer;
                pTargetFeatCursor = targetFeatCls.Insert(true);
                pTargetFeatBuffer = targetFeatCls.CreateFeatureBuffer();

                while ((pSourceFeature = pFeatCurSource.NextFeature()) != null)
                {
                    count++;
                    progressBar.Value = count;

                    if (!SetAllAttributeValue(pSourceFeature, count, pTargetFeatBuffer, ref errFieldindexs, fieldRelation, targetFeatCls, sourceFeatCls))
                    {
                        LogHelper.WriteLog("要素" + pSourceFeature.OID + "转换失败，属性赋值出错", zjgisLogType.zjgisLogError);
                        errorCount++;
                        continue;
                    }

                    switch (pSourceFeature.FeatureType)
                    {
                        case esriFeatureType.esriFTSimple:
                            if (!SetShapeValue(pSourceFeature.ShapeCopy, count, pTargetFeatBuffer, targetFeatCls, pSourceFeature.OID, pTransformation))
                            {
                                errorCount++;
                                continue;
                            }
                            break;

                        case esriFeatureType.esriFTAnnotation:

                            if (!SetAnnoValue(pSourceFeature as IAnnotationFeature, pTargetFeatBuffer as IAnnotationFeature,pTransformation))
                            {
                                errorCount++;
                                continue;
                            }
                            break;

                        //case esriFeatureType.esriFTCoverageAnnotation:
                        //    if (!SetAnnoAttributesFromDgnAnno(pSourceFeature, pTargetFeatBuffer))
                        //    {
                        //        errorCount++;
                        //        continue;
                        //    }
                        //    break;

                        default://其它类型暂不支持
                            errorCount++;
                            continue;
                    }

                    //插入要素
                    try
                    {
                        pTargetFeatCursor.InsertFeature(pTargetFeatBuffer);
                    }
                    catch (Exception e)
                    {
                        LogHelper.WriteLog("要素[" + pSourceFeature.OID + "]转换失败：" + e.Message, zjgisLogType.zjgisLogError);
                        errorCount++;
                        continue;
                    }

                    if (count % 1000 == 0)
                    {
                        pTargetFeatCursor.Flush();
                    }

                    //try
                    //{
                    //    if (delete) pSourceFeature.Delete();
                    //}
                    //catch (Exception e)
                    //{
                    //    //报一次就可以了
                    //    if (!deleteErr)
                    //    {
                    //        deleteErr = true;
                    //       LogHelper.WriteErrLog("删除数据源[" + sourceFeatCls.AliasName + "]中的要素出错：" + e.Message);
                    //    }
                    //}

                    rightCount++;

                    Application.DoEvents();
                    //if (stopAnyway)
                    //    return false;
                }

                pTargetFeatCursor.Flush();
                Marshal.ReleaseComObject(pTargetFeatCursor);
                #endregion

                errFieldindexs = null;

                Marshal.ReleaseComObject(pFeatCurSource);

                //如果保存目标要素失败，则表示所有的要素入库都失败
                try
                {

                    if (needInEditSeesionTarget) StopEidt(targetFeatCls);
                }
                catch (Exception e)
                {
                    rightCount = 0;
                    errorCount = totalCount;
                    LogHelper.WriteLog("保存目标数据出现异常：" + e.Message + "待转换的" + totalCount + "个要素均导入失败！\n", zjgisLogType.zjgisLogError);
                }
                //try
                //{
                //    if (needInEditSessionSource) StopEidt(sourceFeatCls);
                //}
                //catch (Exception e)
                //{
                //   LogHelper.WriteErrLog("保存删除过后的数据源出现异常，删除源数据失败！" + e.Message + "\n");
                //}

                //release the exclusive lock
                ISchemaLock pSchemaLock = targetFeatCls as ISchemaLock;
                pSchemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);

                if (errorCount == 0)
                    LogHelper.WriteLog("要素类转换完毕。待转换总数：" + totalCount + "；成功：" + rightCount + "；失败：" + errorCount + "\n");
                else
                    LogHelper.WriteLog("要素类转换完毕。待转换总数：" + totalCount + "；成功：" + rightCount + "；失败：" + errorCount + "\n", zjgisLogType.zjgisLogError);

                return true;
            }
            catch (Exception e)
            {
                rightCount = 0;
                errorCount = totalCount;

                LogHelper.WriteLog("要素类转换失败：" + e.Message + "\n", zjgisLogType.zjgisLogError);
                return false;
            }
        }

        /// <summary>
        /// 设置新要素的图形
        /// </summary>
        /// <param name="pGeom"></param>
        /// <param name="count"></param>
        /// <param name="pTargetFeatBuffer"></param>
        /// <param name="pTargetFeatCursor"></param>
        /// <param name="oid"></param>
        private static bool SetShapeValue(IGeometry pGeom, int count, IFeatureBuffer pFeatureBuffer, IFeatureClass targetFeatCls, int oid, ITransformation pTransformation)
        {
            //shape字段赋值
            IFields pFields = targetFeatCls.Fields;

            int index = pFields.FindField(targetFeatCls.ShapeFieldName);
            IField pFieldShape = pFields.get_Field(index);
            IGeometryDef pGeometryDef = pFieldShape.GeometryDef;

            ////裁切用
            //esriGeometryDimension geomDimension = esriGeometryDimension.esriGeometry0Dimension;
            //if (sourceFeatCls.ShapeType == esriGeometryType.esriGeometryPolyline)
            //{
            //    geomDimension = esriGeometryDimension.esriGeometry1Dimension;
            //}
            //else if (sourceFeatCls.ShapeType == esriGeometryType.esriGeometryPolygon)
            //{
            //    geomDimension = esriGeometryDimension.esriGeometry2Dimension;
            //}

            //图形赋值
            try
            {
                if (pGeom == null)
                {
                    LogHelper.WriteLog("要素[" + oid + "]转换失败：图形为空！", zjgisLogType.zjgisLogError);
                    return false;
                }

                //if (pGeometryDef.SpatialReference.HasZPrecision())
                if (pGeometryDef.HasZ)
                    pGeom = GeometryHelper.Geom2Dto3D(pGeom);

                //ITopologicalOperator pTopo = pGeom as ITopologicalOperator;

                //if (!pTopo.IsKnownSimple) pTopo.Simplify();

                ITopologicalOperator2 pTop = pGeom as ITopologicalOperator2;

                if (pTop != null)
                {
                    pTop.IsKnownSimple_2 = false;
                    pTop.Simplify();
                }

                bool bTrans = TransformGeo(pTransformation, pGeom);

                if (bTrans == false)
                {
                    LogHelper.WriteLog("要素[" + oid + "]转换失败：图形转换失败！", zjgisLogType.zjgisLogError);
                    return false;
                }

                pFeatureBuffer.Shape = pGeom;

            }
            catch (Exception e)
            {
                LogHelper.WriteLog("要素[" + oid + "]转换失败：几何字段赋值出错！" + e.Message, zjgisLogType.zjgisLogError);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 设置注记各个属性
        /// </summary>
        /// <param name="pAnnoFeatSource"></param>
        /// <param name="pAnnoFeatTarget"></param>
        /// <returns></returns>
        private static bool SetAnnoValue(IAnnotationFeature pAnnoFeatSource, IAnnotationFeature pAnnoFeatTarget, 
            ITransformation pTransformation)
        {
            try
            {
                //IElement pElement;
                //pElement = pAnnoFeatSource.Annotation;

                //if (pAnnoFeatSource is IFeature)
                //{
                //    IFeature pFeature = pAnnoFeatSource as IFeature;
                //    pElement.Geometry = pFeature.ShapeCopy;
                //}

                //else if (pAnnoFeatSource is IFeatureBuffer)
                //    pElement.Geometry = (pAnnoFeatSource as IFeatureBuffer).Shape;

                //pElement.Geometry = (pAnnoFeatSource as IFeature).ShapeCopy;
                //pAnnoFeatTarget.Annotation = pElement;


                ITextElement pTxtElement = new TextElementClass();
                pTxtElement.Text = ((ITextElement)pAnnoFeatSource.Annotation).Text;
                IElement pElement = pTxtElement as IElement;

                IGeometry pGeo = pAnnoFeatSource.Annotation.Geometry.Envelope.LowerLeft;
                bool bTrans = TransformGeo(pTransformation, pGeo);

                if (bTrans == false)
                {
                    LogHelper.WriteLog("注记[" + (pAnnoFeatSource as IRow).OID + "]转换失败！", zjgisLogType.zjgisLogError);
                    return false;
                }

                pElement.Geometry = pGeo;
                pTxtElement.Symbol = ((ITextElement)pAnnoFeatSource.Annotation).Symbol;
                pTxtElement.Symbol.HorizontalAlignment = esriTextHorizontalAlignment.esriTHACenter;
                pTxtElement.Symbol.VerticalAlignment = esriTextVerticalAlignment.esriTVACenter;
                pAnnoFeatTarget.Annotation = pTxtElement as IElement;

            }
            catch (Exception e)
            {
                LogHelper.WriteLog("注记[" + (pAnnoFeatSource as IRow).OID + "]转换失败！" + e.Message, zjgisLogType.zjgisLogError);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 根据字段对应关系设置新建对象的所有属性信息
        /// </summary>
        /// <param name="pRow"></param>
        /// <param name="count"></param>
        /// <param name="pTargetFeatBuffer"></param>
        private static bool SetAllAttributeValue(IRow pRow, int count, IFeatureBuffer pTargetFeature, ref ArrayList errFieldindexs, Hashtable fieldRelation, IFeatureClass targetFeatCls, IFeatureClass sourceFeatCls)
        {
            int targetFieldIndex;
            int sourceFieldIndex;

            //所有字段赋值
            foreach (object targetFieldName in fieldRelation.Keys)
            {
                sourceFieldIndex = pRow.Fields.FindField(fieldRelation[targetFieldName].ToString());
                targetFieldIndex = pTargetFeature.Fields.FindField(targetFieldName.ToString());

                if (targetFieldIndex == -1 ||
                    !targetFeatCls.Fields.get_Field(targetFieldIndex).Editable) continue;

                ////判断是否有默认值设置，就算有默认值，也以数据源的信息优先，只有当数据源找不到相关的字段时，才用默认值
                //bool exsitDefaultValue = false;
                //object objectFieldDefaultValue = null;
                //if (fieldDefaultValue != null)
                //{
                //    foreach (object objDefaultValue in fieldDefaultValue.Keys)
                //    {
                //        if (objDefaultValue.ToString() == targetFieldName.ToString() &&
                //            !String.IsNullOrEmpty(fieldDefaultValue[objDefaultValue].ToString()))
                //        {
                //            exsitDefaultValue = true;
                //            objectFieldDefaultValue = fieldDefaultValue[objDefaultValue];
                //            break;
                //        }
                //    }
                //}

                if (!SetAttributeValue(pRow, pTargetFeature, fieldRelation[targetFieldName].ToString(), targetFieldIndex, count,
                     ref errFieldindexs, sourceFeatCls)) return false;

            }

            return true;
        }

        /// <summary>
        /// 给目标要素赋属性
        /// </summary>
        /// <param name="pRow">数据源</param>
        /// <param name="pFeature">目标要素</param>
        /// <param name="fieldName">数据源字段，可以是表达式</param>
        /// <param name="index">目标要素字段序号</param>
        /// <param name="count">当前个数</param>
        private static bool SetAttributeValue(IRow pRow, IFeatureBuffer pFeatureBufrer, string fieldName, int index, int count, ref ArrayList errFieldindexs, IFeatureClass sourceFeatCls)
        {
            ////首先判断是否是表达式
            //bool isExpression;
            //isExpression = fieldName.Contains('[');

            //object value;

            //bool err = false;//是否出现错误
            //string msg = "";//错误信息

            //try
            //{
            //    if (isExpression)
            //    {
            //        #region 需要进行表达式计算
            //        //仅支持数值型和字符串型的表达式计算，而且类型必须一致，要么都是字符串型，要么都是数值型
            //        if ((int)pFeature.Fields.get_Field(index).Type > 4)
            //        {
            //            msg = "计算目标字段[" + pFeature.Fields.get_Field(index).Name + "]表达式失败，目前只支持数字和字符串型的计算。";
            //            return SetAttributeValueErrOccur(pRow, pFeature, index, count, msg, ref errFieldindexs);
            //        }

            //        Regex r = new Regex(@"\[\w*\]");
            //        MatchCollection m = r.Matches(fieldName);

            //        int numCount = 0;//表达式中对应数据源的字段为数值型的个数
            //        int strCount = 0;//表达式中对应数据源的字段为字符串型的个数

            //        string strResult = "";

            //        foreach (Match match in m)
            //        {
            //            string subFieldName = match.Captures[0].ToString().Trim().Replace("[", "").Replace("]", "").Replace(" ", "");
            //            int sourceFieldIndex = pRow.Fields.FindField(subFieldName);

            //            #region 计算面积
            //            //如果数据源中找得到“面积”、“长度”、“周长”字段的话，以字段的值优先
            //            if (sourceFieldIndex == -1 && subFieldName == "面积")
            //            {
            //                if (pRow is IFeature)
            //                {
            //                    if (((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
            //                    {
            //                        IArea pArea = ((IFeature)pRow).Shape as IArea;
            //                        fieldName = fieldName.Replace(subFieldName.Trim(), pArea.Area.ToString());
            //                    }
            //                    else
            //                    {
            //                        msg = "数据源[" + sourceFeatCls.AliasName + "]几何类型不是多边形，无法计算目标字段[" +
            //                                pFeature.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
            //                        err = true;
            //                    }
            //                }
            //                else
            //                {
            //                    msg = "数据源[" + sourceFeatCls.AliasName + "]不是多要素类，无法计算目标字段[" +
            //                        pFeature.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
            //                    err = true;
            //                }
            //                numCount++;
            //            }
            //            #endregion

            //            #region 计算长度或者周长
            //            else if (sourceFieldIndex == -1 && (subFieldName == "长度" || subFieldName == "周长"))
            //            {
            //                if (pRow is IFeature)
            //                {
            //                    if (((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolyline ||
            //                        ((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
            //                    {
            //                        IPolyline pPolyline = ((IFeature)pRow).Shape as IPolyline;
            //                        fieldName = fieldName.Replace((subFieldName.Trim()), pPolyline.Length.ToString());
            //                    }
            //                    else
            //                    {
            //                        msg = "数据源[" + sourceFeatCls.AliasName + "]几何类型不是线，无法计算目标字段[" +
            //                             pFeature.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
            //                        err = true;
            //                    }
            //                }
            //                else
            //                {
            //                    msg = "数据源[" + sourceFeatCls.AliasName + "]不是多要素类，无法计算目标字段[" +
            //                        pFeature.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
            //                    err = true;
            //                }
            //                numCount++;
            //            }
            //            #endregion

            //            #region 计算字段的值
            //            else
            //            {
            //                //一旦有一个字段不存在，则整个算数表达式就不要算了
            //                if (sourceFieldIndex < 0)
            //                {
            //                    msg = "数据源[" + sourceFeatCls.AliasName + "]字段[" + subFieldName + "]不存在，表达式无法计算";
            //                    err = true;
            //                }
            //                else
            //                {
            //                    //判断字段数字型和字符串型的个数。如果是数字，则需要计算；如果是字符串，则直接合并
            //                    if (pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeDouble ||
            //                       pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeSingle ||
            //                       pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeInteger ||
            //                       pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeSmallInteger)
            //                    {
            //                        //如果类型为数值型时为空，则取0
            //                        if (pRow.get_Value(sourceFieldIndex) == null || Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
            //                            string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
            //                        {
            //                            value = 0;
            //                        }
            //                        else
            //                        {
            //                            value = pRow.get_Value(sourceFieldIndex).ToString();
            //                        }
            //                        fieldName = fieldName.Replace(("[" + subFieldName.Trim() + "]"), value.ToString());
            //                        numCount++;
            //                    }
            //                    //对于字符串型的计算，只能作合并，不管连接运算符是+ - * 还是/，一律用+作
            //                    else if (pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeString)
            //                    {
            //                        //如果类型为字符串型时为空，则取空字符串""
            //                        if (pRow.get_Value(sourceFieldIndex) == null || Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
            //                            string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
            //                        {
            //                            value = "";
            //                        }
            //                        else
            //                        {
            //                            value = pRow.get_Value(sourceFieldIndex).ToString();
            //                        }
            //                        strResult = strResult + value;
            //                        strCount++;
            //                    }
            //                }
            //            }
            //            #endregion

            //            if (err) return SetAttributeValueErrOccur(pRow, pFeature, index, count, msg, ref errFieldindexs);
            //        }

            //        if (m.Count > 0)
            //        {
            //            if (numCount == m.Count)//全部数字，直接计算
            //            {
            //                object objResult;
            //                try
            //                {
            //                    objResult = expression.Evalute(fieldName);
            //                }
            //                catch (Exception e)
            //                {
            //                    msg = "计算目标字段[" + pFeature.Fields.get_Field(index).Name + "]表达式出错！" + e.Message;
            //                    return SetAttributeValueErrOccur(pRow, pFeature, index, count, msg, ref errFieldindexs);
            //                }
            //                pFeature.set_Value(index, objResult);
            //                return true;
            //            }
            //            else if (strCount == m.Count)//全部字符串，直接赋值
            //            {
            //                pFeature.set_Value(index, strResult);
            //                return true;
            //            }
            //            else
            //            {
            //                msg = "目标字段[" + pFeature.Fields.get_Field(index).Name +
            //                    "]的表达式对应的数据源字段既有数字型又有数值型，无法计算。";
            //                err = true;
            //            }
            //        }
            //        else
            //        {
            //            msg = "解析目标字段[" + pFeature.Fields.get_Field(index).Name + "]对应的表达式失败！";
            //            err = true;
            //        }

            //        if (err) return SetAttributeValueErrOccur(pRow, pFeature, index, count, msg, ref errFieldindexs);
            //        #endregion
            //    }
            //    else
            //    {
            //        #region 不需要计算，直接赋值
            //        int sourceFieldIndex = pRow.Fields.FindField(fieldName);

            //        #region 默认值处理
            //        //如果数据源字段不存在，而有默认值，则直接赋默认值
            //        if (sourceFieldIndex == -1 && exitDefaultValue)
            //        {
            //            pFeature.set_Value(index, fieldDefaultValue[pFeature.Fields.get_Field(index).Name]);
            //            return true;
            //        }
            //        #endregion

            //        #region 空值处理
            //        //如果数据源字段不存在，或者为空
            //        if (sourceFieldIndex == -1 || pRow.get_Value(sourceFieldIndex) == null ||
            //            Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
            //            string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
            //        {
            //            msg = "数据源字段[" + fieldName + "]有值为空。";

            //            return SetAttributeValueErrOccur(pRow, pFeature, index, count, msg, ref errFieldindexs);
            //        }
            //        #endregion

            //        #region 处理旋转角度字段
            //        try
            //        {
            //            if (SystemConfig.systemConfigXml.符号化.角度字段 == fieldName)
            //            {
            //                //先取入库依据字段，如果没有，则到系统配置文件中取符号化依据字段
            //                string fcodeName = sourceCodeName != "" ? sourceCodeName : fieldRelation[SystemConfig.systemConfigXml.符号化.符号化字段].ToString(); ;
            //                if (fcodeName != "")
            //                {
            //                    int fcodeIndex = pRow.Fields.FindField(fcodeName);
            //                    if (fcodeIndex >= 0)
            //                    {
            //                        string fcodeValue = pRow.get_Value(fcodeIndex).ToString();

            //                        //如果有代码转换关系，需要进行转换后再判断
            //                        if (fcodeRelation != null && fcodeRelation.Contains(fcodeValue))
            //                            fcodeValue = fcodeRelation[fcodeValue].ToString();

            //                        //倒数第三位图形码为1，说明是无向点
            //                        Match match = Regex.Match(fcodeValue, @"\d\d\d\d\d\d1\d\d");
            //                        if (match.Success)
            //                        {
            //                            pFeature.set_Value(sourceFieldIndex, DBNull.Value);
            //                            return true;
            //                        }
            //                    }
            //                }
            //            }

            //        }
            //        catch (Exception ex)
            //        {
            //           LogHelper.WriteErrLog("对原始要素[" + pRow.OID + "]设置无向点的旋转角度为空失败，将以默认的形式进行处理！");
            //        }
            //        #endregion

            //        value = pRow.get_Value(sourceFieldIndex);

            //        //#region 代码转换
            //        ////如果有入库依据字段，代码对应关系，需判断是否要转换
            //        //if (sourceCodeName != "" && fieldName == sourceCodeName && fcodeRelation != null &&
            //        //    fcodeRelation.ContainsKey(value.ToString()))
            //        //    value = fcodeRelation[value.ToString()];
            //        //#endregion

            //        pFeature.set_Value(index, value.ToString());

            //        #endregion
            //    }
            //    return true;
            //}
            //catch (Exception e)
            //{
            //    msg = "获取目标数据[" + pRow.OID + "]字段[" + pFeature.Fields.get_Field(index).Name + "]值出错：" + e.Message;
            //    //之所以这里count强行赋值为1，是为了每次出现异常都需要提示用户
            //    return SetAttributeValueErrOccur(pRow, pFeature, index, 1, msg, ref errFieldindexs);
            //}

            //首先判断是否是表达式
            bool isExpression;
            isExpression = fieldName.Contains('[');

            object value;

            bool err = false;//是否出现错误
            string msg = "";//错误信息

            Expression expression = new Expression();

            try
            {
                if (isExpression)
                {
                    #region 需要进行表达式计算
                    //仅支持数值型和字符串型的表达式计算，而且类型必须一致，要么都是字符串型，要么都是数值型
                    if ((int)pFeatureBufrer.Fields.get_Field(index).Type > 4)
                    {
                        msg = "计算目标字段[" + pFeatureBufrer.Fields.get_Field(index).Name + "]表达式失败，目前只支持数字和字符串型的计算。";
                        return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, count, msg, ref errFieldindexs);
                    }

                    Regex r = new Regex(@"\[\w*\]");
                    MatchCollection m = r.Matches(fieldName);

                    int numCount = 0;//表达式中对应数据源的字段为数值型的个数
                    int strCount = 0;//表达式中对应数据源的字段为字符串型的个数

                    string strResult = "";

                    foreach (Match match in m)
                    {
                        string subFieldName = match.Captures[0].ToString().Trim().Replace("[", "").Replace("]", "").Replace(" ", "");
                        int sourceFieldIndex = pRow.Fields.FindField(subFieldName);

                        #region 计算面积
                        //如果数据源中找得到“面积”、“长度”、“周长”字段的话，以字段的值优先
                        if (sourceFieldIndex == -1 && subFieldName == "面积")
                        {
                            if (pRow is IFeature)
                            {
                                if (((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                                {
                                    IArea pArea = ((IFeature)pRow).Shape as IArea;
                                    fieldName = fieldName.Replace(subFieldName.Trim(), pArea.Area.ToString());
                                }
                                else
                                {
                                    msg = "数据源[" + sourceFeatCls.AliasName + "]几何类型不是多边形，无法计算目标字段[" +
                                            pFeatureBufrer.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                    err = true;
                                }
                            }
                            else
                            {
                                msg = "数据源[" + sourceFeatCls.AliasName + "]不是多要素类，无法计算目标字段[" +
                                    pFeatureBufrer.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                err = true;
                            }
                            numCount++;
                        }
                        #endregion

                        #region 计算长度或者周长
                        else if (sourceFieldIndex == -1 && (subFieldName == "长度" || subFieldName == "周长"))
                        {
                            if (pRow is IFeature)
                            {
                                if (((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolyline ||
                                    ((IFeature)pRow).Shape.GeometryType == esriGeometryType.esriGeometryPolygon)
                                {
                                    IPolyline pPolyline = ((IFeature)pRow).Shape as IPolyline;
                                    fieldName = fieldName.Replace((subFieldName.Trim()), pPolyline.Length.ToString());
                                }
                                else
                                {
                                    msg = "数据源[" + sourceFeatCls.AliasName + "]几何类型不是线，无法计算目标字段[" +
                                         pFeatureBufrer.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                    err = true;
                                }
                            }
                            else
                            {
                                msg = "数据源[" + sourceFeatCls.AliasName + "]不是多要素类，无法计算目标字段[" +
                                    pFeatureBufrer.Fields.get_Field(index).Name + "]中的[" + subFieldName + "]。";
                                err = true;
                            }
                            numCount++;
                        }
                        #endregion

                        #region 计算字段的值
                        else
                        {
                            //一旦有一个字段不存在，则整个算数表达式就不要算了
                            if (sourceFieldIndex < 0)
                            {
                                msg = "数据源[" + sourceFeatCls.AliasName + "]字段[" + subFieldName + "]不存在，表达式无法计算";
                                err = true;
                            }
                            else
                            {
                                //判断字段数字型和字符串型的个数。如果是数字，则需要计算；如果是字符串，则直接合并
                                if (pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeDouble ||
                                   pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeSingle ||
                                   pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeInteger ||
                                   pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeSmallInteger)
                                {
                                    //如果类型为数值型时为空，则取0
                                    if (pRow.get_Value(sourceFieldIndex) == null || Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
                                        string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
                                    {
                                        value = 0;
                                    }
                                    else
                                    {
                                        value = pRow.get_Value(sourceFieldIndex).ToString();
                                    }
                                    fieldName = fieldName.Replace(("[" + subFieldName.Trim() + "]"), value.ToString());
                                    numCount++;
                                }
                                //对于字符串型的计算，只能作合并，不管连接运算符是+ - * 还是/，一律用+作
                                else if (pRow.Fields.get_Field(sourceFieldIndex).Type == esriFieldType.esriFieldTypeString)
                                {
                                    //如果类型为字符串型时为空，则取空字符串""
                                    if (pRow.get_Value(sourceFieldIndex) == null || Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
                                        string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
                                    {
                                        value = "";
                                    }
                                    else
                                    {
                                        value = pRow.get_Value(sourceFieldIndex).ToString();
                                    }
                                    strResult = strResult + value;
                                    strCount++;
                                }
                            }
                        }
                        #endregion

                        if (err) return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, count, msg, ref errFieldindexs);
                    }

                    if (m.Count > 0)
                    {
                        if (numCount == m.Count)//全部数字，直接计算
                        {
                            object objResult;
                            try
                            {
                                objResult = expression.Evalute(fieldName);
                            }
                            catch (Exception e)
                            {
                                msg = "计算目标字段[" + pFeatureBufrer.Fields.get_Field(index).Name + "]表达式出错！" + e.Message;
                                return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, count, msg, ref errFieldindexs);
                            }
                            pFeatureBufrer.set_Value(index, objResult);
                            return true;
                        }
                        else if (strCount == m.Count)//全部字符串，直接赋值
                        {
                            pFeatureBufrer.set_Value(index, strResult);
                            return true;
                        }
                        else
                        {
                            msg = "目标字段[" + pFeatureBufrer.Fields.get_Field(index).Name +
                                "]的表达式对应的数据源字段既有数字型又有数值型，无法计算。";
                            err = true;
                        }
                    }
                    else
                    {
                        msg = "解析目标字段[" + pFeatureBufrer.Fields.get_Field(index).Name + "]对应的表达式失败！";
                        err = true;
                    }

                    if (err) return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, count, msg, ref errFieldindexs);
                    #endregion
                }
                else
                {
                    #region 不需要计算，直接赋值
                    int sourceFieldIndex = pRow.Fields.FindField(fieldName);

                    //#region 默认值处理
                    ////如果数据源字段不存在，而有默认值，则直接赋默认值
                    //if (sourceFieldIndex == -1 && exitDefaultValue)
                    //{
                    //    pFeatureBufrer.set_Value(index, fieldDefaultValue[pFeatureBufrer.Fields.get_Field(index).Name]);
                    //    return true;
                    //}
                    //#endregion

                    #region 空值处理
                    //如果数据源字段不存在，或者为空
                    if (sourceFieldIndex == -1 || pRow.get_Value(sourceFieldIndex) == null ||
                        Convert.IsDBNull(pRow.get_Value(sourceFieldIndex)) ||
                        string.IsNullOrEmpty(pRow.get_Value(sourceFieldIndex).ToString()))
                    {
                        msg = "数据源字段[" + fieldName + "]有值为空。";

                        return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, count, msg, ref errFieldindexs);
                    }
                    #endregion

                    //#region 处理旋转角度字段
                    //try
                    //{
                    //    if (SystemConfig.systemConfigXml.符号化.角度字段 == fieldName)
                    //    {
                    //        //先去入库依据字段，如果没有，则到系统配置文件中取符号化依据字段
                    //        string fcodeName = sourceCodeName != "" ? sourceCodeName : fieldRelation[SystemConfig.systemConfigXml.符号化.符号化字段].ToString(); ;
                    //        if (fcodeName != null && fcodeName != "")
                    //        {
                    //            int fcodeIndex = pRow.Fields.FindField(fcodeName);
                    //            if (fcodeIndex >= 0)
                    //            {
                    //                string fcodeValue = pRow.get_Value(fcodeIndex).ToString();

                    //                //如果有代码转换关系，需要进行转换后再判断
                    //                if (fcodeRelation != null && fcodeRelation.Contains(fcodeValue))
                    //                    fcodeValue = fcodeRelation[fcodeValue].ToString();

                    //                //倒数第三位图形码为1，说明是无向点
                    //                Match match = Regex.Match(fcodeValue, @"\d\d\d\d\d\d1\d\d");
                    //                if (match.Success)
                    //                {
                    //                    pFeatureBufrer.set_Value(sourceFieldIndex, DBNull.Value);
                    //                    return true;
                    //                }
                    //            }
                    //        }
                    //    }

                    //}
                    //catch (Exception ex)
                    //{
                    //   LogHelper.WriteErrLog("对原始要素[" + pRow.OID + "]设置无向点的旋转角度为空失败，将以默认的形式进行处理！");
                    //}
                    //#endregion

                    value = pRow.get_Value(sourceFieldIndex);

                    //#region 代码转换
                    ////如果有入库依据字段，代码对应关系，需判断是否要转换
                    //if (sourceCodeName != "" && fieldName == sourceCodeName && fcodeRelation != null &&
                    //    fcodeRelation.ContainsKey(value.ToString()))
                    //    value = fcodeRelation[value.ToString()];
                    //#endregion

                    pFeatureBufrer.set_Value(index, value);

                    #endregion
                }
                return true;
            }
            catch (Exception e)
            {
                msg = "获取目标数据[" + pRow.OID + "]字段[" + pFeatureBufrer.Fields.get_Field(index).Name + "]值出错：" + e.Message;
                //之所以这里count强行赋值为1，是为了每次出现异常都需要提示用户
                return SetAttributeValueErrOccur(pRow, pFeatureBufrer, index, 1, msg, ref errFieldindexs);
            }
        }

        /// <summary>
        /// 转属性出错时，如果目标要素该属性可以为空，则直接赋空值，如果不能为空，则数值型赋为0，字符串型赋为""，再第一次出现时，给出提示；
        /// 否则转该要素时会出错，则记下所有出错的要素ID
        /// </summary>
        /// <param name="pRow"></param>
        /// <param name="pFeature"></param>
        /// <param name="fieldName"></param>
        /// <param name="index"></param>
        /// <param name="count"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        private static bool SetAttributeValueErrOccur(IRow pRow, IFeatureBuffer pFeatureBufrer, int index, int count, string msg, ref ArrayList errFieldindexs)
        {
            //如果该字段以前没出过错，现在出错了，那么强行将count赋为1，这样可以给出提示，并将该字段的索引加入导errFieldindexs，下次就可以不用提示了
            if (!errFieldindexs.Contains(index))
            {
                count = 1;
                errFieldindexs.Add(index);
            }

            if (pFeatureBufrer.Fields.get_Field(index).IsNullable)
            {
                pFeatureBufrer.set_Value(index, DBNull.Value);
                if (count == 1)
                    LogHelper.WriteLog(msg + "系统自动将其对应的目标字段[" + pFeatureBufrer.Fields.get_Field(index).AliasName + "]赋空值。");
                return true;
            }
            else
            {
                switch (pFeatureBufrer.Fields.get_Field(index).Type)
                {
                    case esriFieldType.esriFieldTypeSmallInteger:
                    case esriFieldType.esriFieldTypeInteger:
                    case esriFieldType.esriFieldTypeDouble:
                    case esriFieldType.esriFieldTypeSingle:
                        pFeatureBufrer.set_Value(index, 0);
                        if (count == 1) LogHelper.WriteLog(msg + "系统自动将其对应的目标字段[" + pFeatureBufrer.Fields.get_Field(index).AliasName + "]赋0");
                        return true;
                    case esriFieldType.esriFieldTypeString:
                        if (count == 1) LogHelper.WriteLog(msg + "系统自动将其对应的目标字段[" + pFeatureBufrer.Fields.get_Field(index).AliasName + "]赋空字符串（\"\"）");
                        pFeatureBufrer.set_Value(index, "");
                        return true;
                    default:
                        LogHelper.WriteLog("要素[" + pRow.OID + "]转换失败！" + msg, zjgisLogType.zjgisLogError);
                        return false;
                }
            }

        }

        /// <summary>
        /// 如果要素类是远程数据库类型，并且进行过注册，那么对要素的修改必须要开打编辑
        /// </summary>
        /// <param name="pFeatCls"></param>
        /// <returns></returns>
        private static bool NeedInEditSession(IFeatureClass pFeatCls)
        {
            IDataset pDataset = pFeatCls as IDataset;
            IWorkspace pWorkspace = pDataset.Workspace;
            if (pWorkspace.Type != esriWorkspaceType.esriRemoteDatabaseWorkspace) return false;

            bool IsRegistered;
            bool IsMovingEditsToBase;

            IVersionedObject3 versionObj = pFeatCls as IVersionedObject3;
            versionObj.GetVersionRegistrationInfo(out IsRegistered, out IsMovingEditsToBase);
            return IsRegistered;
        }

        /// <summary>
        /// 打开编辑
        /// </summary>
        /// <param name="pFeatCls"></param>
        private static void StartEdit(IFeatureClass pFeatCls)
        {
            IDataset pDataset = pFeatCls as IDataset;
            IWorkspace pWorkspace = pDataset.Workspace;
            //if (pWorkspace.Type != esriWorkspaceType.esriRemoteDatabaseWorkspace) return;

            IWorkspaceEdit pWsEdit = pWorkspace as IWorkspaceEdit;

            pWsEdit.StartEditing(false);
            pWsEdit.StartEditOperation();

            return;
        }

        /// <summary>
        /// 结束编辑
        /// </summary>
        /// <param name="pFeatCls"></param>
        private static void StopEidt(IFeatureClass pFeatCls)
        {
            IDataset pDataset = pFeatCls as IDataset;
            IWorkspace pWorkspace = pDataset.Workspace;
            //if (pWorkspace.Type != esriWorkspaceType.esriRemoteDatabaseWorkspace) return;

            IWorkspaceEdit pWsEdit = pWorkspace as IWorkspaceEdit;

            pWsEdit.StopEditOperation();
            pWsEdit.StopEditing(true);

            return;
        }
    }
}
